package com.alone.mybatisplus.datascope.core.loader;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.RandomUtil;
import com.alone.mybatisplus.datascope.conts.DataScopeModel;
import com.alone.mybatisplus.datascope.core.domain.ModelDataScope;

import java.util.*;

/**
 * 根据当前用户以及授权的数据模块信息加载数据权限
 *
 * @author Alone
 * @see RoutingDataScopeLoader
 */
public abstract class DataScopeHandler implements DataScopeLoader {

    /**
     * template method
     *
     * @param dataScope 数据范围
     */
    @Override
    public void loadFilterValue(ModelDataScope dataScope) {

        // todo
        Long currentId = RandomUtil.randomLong(1L, 5L);

        DataScopeModel model = dataScope.getModel();

        if (allowAll(currentId, model)) {
            dataScope.setAllowAll(true);
            return;
        }

        List<Pair<String, Set<?>>> inValue = new ArrayList<>();
        setInValue(currentId, model, inValue);
        if (CollUtil.isNotEmpty(inValue)) {
            for (Pair<String, Set<?>> pair : inValue) {
                dataScope.addInValue(pair.getKey(), pair.getValue());
            }
        }

        List<Pair<String, Set<?>>> notInValue = new ArrayList<>();
        setNotInValue(currentId, model, notInValue);
        if (CollUtil.isNotEmpty(notInValue)) {
            for (Pair<String, Set<?>> pair : notInValue) {
                dataScope.addNotInValue(pair.getKey(), pair.getValue());
            }
        }

    }

    /**
     * 是否能够处理当前数据权限模型
     *
     * @param model 数据权限模型
     * @return boolean
     */
    public abstract boolean canHandle(DataScopeModel model);

    /**
     * 是否查看全部
     *
     * @param userId 用户id
     * @param model  数据权限模块
     * @return boolean
     */
    public boolean allowAll(Long userId, DataScopeModel model) {
        return false;
    }

    /**
     * 获取in拼接的条件
     *
     * @param userId 用户id
     * @param model  数据权限模块
     * @return list
     */
    protected void setInValue(Long userId, DataScopeModel model, List<Pair<String, Set<?>>> inValue) {
    }

    /**
     * 获取not in拼接的条件
     *
     * @param userId 用户id
     * @param model  数据权限模块
     * @return list
     */
    protected void setNotInValue(Long userId, DataScopeModel model, List<Pair<String, Set<?>>> notInValue) {
    }

}
